package com.EAsystem.aop;

import com.EAsystem.annotation.RequireRole;
import com.EAsystem.entity.User;
import com.EAsystem.utils.SessionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 权限检查AOP切面
 * 用于处理@RequireRole注解的权限验证
 */
@Aspect
@Component
public class RoleCheckAspect {

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 环绕通知，处理带有@RequireRole注解的方法
     */
    @Around("@annotation(requireRole)")
    public Object checkRole(ProceedingJoinPoint joinPoint, RequireRole requireRole) throws Throwable {
        // 获取当前请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RuntimeException("无法获取当前请求");
        }
        
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        
        // 获取当前用户
        User currentUser = SessionUtils.getCurrentUser(request);
        if (currentUser == null) {
            // 用户未登录
            return handleUnauthorized(request, response, "用户未登录，请先登录");
        }
        
        // 如果允许所有已登录用户访问
        if (requireRole.allowAll()) {
            return joinPoint.proceed();
        }
        
        // 检查用户角色权限
        int[] allowedRoles = requireRole.value();
        if (allowedRoles.length == 0) {
            return joinPoint.proceed();
        }
        
        Integer userRole = currentUser.getRole();
        if (userRole == null || !Arrays.stream(allowedRoles).anyMatch(role -> role == userRole)) {
            return handleUnauthorized(request, response, "权限不足，无法访问该资源");
        }

        return joinPoint.proceed();
    }

    /**
     * 环绕通知，处理类级别的@RequireRole注解
     */
    @Around("@within(requireRole)")
    public Object checkClassRole(ProceedingJoinPoint joinPoint, RequireRole requireRole) throws Throwable {
        return checkRole(joinPoint, requireRole);
    }

    /**
     * 处理未授权请求
     */
    private Object handleUnauthorized(HttpServletRequest request, HttpServletResponse response, String message) throws IOException {
        // 判断是否为AJAX请求
        boolean isAjax = isAjaxRequest(request);
        
        if (isAjax) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", message);
            errorResponse.put("code", 401);
            
            response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
            return null;
        } else {
            String redirectUrl = request.getContextPath() + "/user/login";
            response.sendRedirect(redirectUrl);
            return null;
        }
    }

    /**
     * 判断是否为AJAX请求
     */
    private boolean isAjaxRequest(HttpServletRequest request) {
        // 检查请求头
        String requestedWith = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equals(requestedWith)) {
            return true;
        }

        String accept = request.getHeader("Accept");
        if (accept != null && accept.contains("application/json")) {
            return true;
        }

        String contentType = request.getContentType();
        if (contentType != null && contentType.contains("application/json")) {
            return true;
        }

        String requestURI = request.getRequestURI();
        if (requestURI != null && (requestURI.contains("/api/") || 
                                  requestURI.endsWith(".json") ||
                                  request.getParameter("ajax") != null)) {
            return true;
        }
        
        return false;
    }

    /**
     * 根据用户角色获取重定向URL
     */
    private String getRedirectUrlByRole(String contextPath, Integer userRole) {
        if (userRole == null) {
            return contextPath + "/user/login";
        }
        
        switch (userRole) {
            case 1:
                return contextPath + "/admin/home";
            case 2:
                return contextPath + "/teacher/home";
            case 3:
                return contextPath + "/student/home";
            default:
                return contextPath + "/user/login";
        }
    }
} 